package edu.fudan.jwxt.controller;


import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import edu.fudan.jwxt.annotation.Adminer;
import edu.fudan.jwxt.annotation.AdminerOrTeacher;
import edu.fudan.jwxt.common.Constants;
import edu.fudan.jwxt.common.ResultBody;
import edu.fudan.jwxt.common.RoleConstant;
import edu.fudan.jwxt.dto.PasswordDto;
import edu.fudan.jwxt.dto.PersonInfo;
import edu.fudan.jwxt.dto.UserDto;
import edu.fudan.jwxt.entity.User;
import edu.fudan.jwxt.service.UserService;
import edu.fudan.jwxt.utils.CheckCodeUtil;
import edu.fudan.jwxt.utils.RoleCheckUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResultBody Login(@RequestBody UserDto userDto) throws IOException {

        String password = userDto.getPassword();
        //密码进行加密
        password = SecureUtil.sha256(password);
        userDto.setPassword(password);

        UserDto userD = userService.login(userDto);

        return ResultBody.success(userD);
    }

    //TODO: 用户权限检查
    @GetMapping
    public ResultBody UserListAll(){

        RoleCheckUtil.CheckUserAdmin();

        List<User> users = userService.list();
        List<PersonInfo> personInfos = PersonInfo.toPersonInfoList(users);

        return ResultBody.success(personInfos);
    }

    ////TODO: 用户权限检查OrTeacher
    @GetMapping("/{uid}")
    public ResultBody getUser(@PathVariable String uid){
        //RoleCheckUtil.CheckUserUID(uid);

        User user = userService.getById(uid);
        PersonInfo personInfo;
        personInfo = PersonInfo.getPersonIfo(user);

        return ResultBody.success(personInfo);
    }

    @GetMapping("/teachers")
    public ResultBody getTeachers(){
        LambdaQueryWrapper<User> q = new LambdaQueryWrapper<>();
        q.eq(User::getRole, RoleConstant.TEACHER);

        List<User> users = userService.list(q);
        List<PersonInfo> personInfos = PersonInfo.toPersonInfoList(users);
        JSONArray jsonArray = new JSONArray();
        for(PersonInfo personInfo : personInfos){
            JSONObject jsonObject = new JSONObject();
            jsonObject.append(personInfo.getUid(),personInfo);
            jsonArray.add(jsonObject);
        }
        return ResultBody.success(jsonArray);
    }

    @GetMapping("page/{current}/{size}")
    public ResultBody UserPageList(@PathVariable int current, @PathVariable int size){
        RoleCheckUtil.CheckUserAdmin();

        IPage<User> page = new Page<>(current,size);
        List<User> users = userService.page(page).getRecords();

        List<PersonInfo> personInfos = PersonInfo.toPersonInfoList(users);

        return ResultBody.success(personInfos);
    }

    //用户个人信息修改
    @PostMapping("/update")
    public ResultBody UpdateUser(@RequestBody User user){
        boolean flag = userService.updateById(user);   //根据主键进行用户更新
        return ResultBody.success();
    }

    //用户密码修改
    @PostMapping("/updatepd")
    public ResultBody UpdatePassword(@RequestBody PasswordDto passwordDto){

        userService.updatePassword(passwordDto);

        return ResultBody.success();
    }

    //管理员对用户密码修改
    //TODO: 用户权限检查
    @PostMapping("/changepd")
    public ResultBody adminUpdatePd(@RequestBody PasswordDto passwordDto){

        userService.updatePassword(passwordDto);

        return ResultBody.success();
    }

    //TODO: 用户权限检查
    @PostMapping("/insert")
    public ResultBody Insert(@RequestBody User user){

        userService.save(user);
        return ResultBody.success();
    }

    //批量添加
    //TODO: 用户权限检查
    @PostMapping("/inserts")
    public ResultBody InsertList(MultipartFile file) throws IOException {
        //加载文件
        InputStream inputStream = file.getInputStream();
        InputStreamReader ir = new InputStreamReader(inputStream);

        CsvReader reader = CsvUtil.getReader();
        List<User> users = reader.read(ir,User.class);

        //添加用户
        Map<String,Object> map = userService.saveList(users);

        return ResultBody.success(map);
    }

    //TODO: 用户权限检查
    @DeleteMapping("/{uid}")
    public ResultBody Delete(@PathVariable String uid){
        RoleCheckUtil.CheckUserAdmin();

        boolean flag =  userService.removeById(uid);
        if(flag)
            return ResultBody.success();
        else
            return ResultBody.error(Constants.CODE_600, "ID不存在或已删除");
    }

    //批量删除
    //TODO: 用户权限检查
    @PostMapping("/delete")
    public ResultBody DeleteList(@RequestBody List<UserDto> users){
        int failCount = 0;
        for(UserDto user : users){
            try {
                userService.removeById(user.getUid());
            }catch (Exception e){
                failCount++;
            }
        }
        if(failCount == 0)
            return ResultBody.success();
        else
            return ResultBody.error(Constants.CODE_600,"部分老师无法删除");
    }

    //更新学生状态
    @PostMapping
    public ResultBody UpdateStatus(@RequestBody User user){
        boolean flag = userService.updateStatus(user);

        if(flag)
            return ResultBody.success();
        else
            return ResultBody.error(Constants.CODE_600,"用户不存在");
    }

    //刷新验证码
    @GetMapping("/checkcode")
    public void GetCheckCode(HttpSession session,HttpServletResponse response) throws IOException {
        //生成验证码文件
        ServletOutputStream os = response.getOutputStream();
        String code = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);
        session.setAttribute("checkcode",code);
    }

}

